package com.bdk.middle.orchestration.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bdk.middle.common.domain.PageDO;
import com.bdk.middle.common.result.ResultDO;
import com.bdk.middle.common.status.ErrorCode;
import com.bdk.middle.common.util.BeanUtilsExtends;
import com.bdk.middle.common.util.DateUtil;
import com.bdk.middle.orchestration.api.client.CategoryClientApi;
import com.bdk.middle.orchestration.api.domain.CategoryDO;
import com.bdk.middle.orchestration.api.query.CategoryQueryDO;
import com.bdk.middle.orchestration.core.entity.CategoryEntity;
import com.bdk.middle.orchestration.core.mapper.CategoryMapper;

import com.bdk.middle.orchestration.service.CategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

import java.text.Format;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Reagan
 * @since 2021-03-12
 */
@RestController
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, CategoryEntity> implements CategoryService, CategoryClientApi {

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public ResultDO add(CategoryDO domain) {

        CategoryEntity entity = new CategoryEntity();

        ResultDO result = BeanUtilsExtends.copy(entity, domain);

        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        if (domain.getCategoryId() == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.CATEGORY_CATEGORY_ID_NOT_NULL);
            logger.debug("error code：" + ErrorCode.CATEGORY_CATEGORY_ID_NOT_NULL.getCode() + " msg" + ErrorCode.CATEGORY_CATEGORY_ID_NOT_NULL.getMsg());
            return result;
        }

        result = getMaxCode(domain.getCategoryId(), result);//同级数量

        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        int childCode = (int) result.getModel(ResultDO.FIRST_MODEL_KEY) + 1;

        if (childCode > 99) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.CATEGORY_MAX_100);
            logger.debug("error code：" + ErrorCode.CATEGORY_MAX_100.getCode() + " msg" + ErrorCode.CATEGORY_MAX_100.getMsg());
            return result;
        }

        //不够位数的在前面补0，保留两位数字
        String code = String.format("%02d", childCode);

        //查询父类目的code  如果父类目存在，子类目的code需将父类目的code添加在前
        result = getEntity(domain.getCategoryId(), result);
        CategoryEntity parent = (CategoryEntity) result.getModel(ResultDO.SECOND_MODEL_KEY);
        if (parent != null) {
            code = parent.getCode() + code;
        }

        entity.setCode(code);

        int res = -1;
        try {
            res = categoryMapper.insert(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if (res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.CATEGORY_ADD_ERROR);
            logger.debug("error code：" + ErrorCode.CATEGORY_ADD_ERROR.getCode() + " msg" + ErrorCode.CATEGORY_ADD_ERROR.getMsg());
            return result;
        }

        return result;
    }


    @Override
    public ResultDO edit(CategoryDO domain) {

        CategoryEntity entity = new CategoryEntity();

        ResultDO result = BeanUtilsExtends.copy(entity, domain);

        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        result = getEntity(domain.getId(), result);
        CategoryEntity detail = (CategoryEntity) result.getModel(ResultDO.SECOND_MODEL_KEY);

        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        //当父级id更改了之后  code值也要跟着相应的更改
        if (domain.getCategoryId() != null && !detail.getCategoryId().equals(domain.getCategoryId())) {

            result = getMaxCode(domain.getCategoryId(), result);//同级数量

            if (!result.isSuccess()) {
                logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
                return result;
            }
            int childCode = (int) result.getModel(ResultDO.FIRST_MODEL_KEY) + 1;

            if (childCode > 99) {
                logger.debug("error code：" + ErrorCode.CATEGORY_MAX_100.getCode() + " msg" + ErrorCode.CATEGORY_MAX_100.getMsg());
                return result;
            }

            //不够位数的在前面补0，保留两位数字
            String code = String.format("%02d", childCode);

            //查询父类目的code  子类目的code需将父类目的code添加在前
            result = getEntity(domain.getCategoryId(), result);
            CategoryEntity parent = (CategoryEntity) result.getModel(ResultDO.SECOND_MODEL_KEY);
            if (parent != null) {
                code = parent.getCode() + code;
            }
            entity.setCode(code);
        }

        int res = 0;


        try {
            res = categoryMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否等于0   等于0就代表更新失败
        if (res == 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.CATEGORY_EDIT_ERROR);
            logger.debug("error code：" + ErrorCode.CATEGORY_EDIT_ERROR.getCode() + " msg" + ErrorCode.CATEGORY_EDIT_ERROR.getMsg());
            return result;
        }

        return result;
    }


    @Override
    public ResultDO get(String id) {
        ResultDO result = new ResultDO();

        CategoryEntity entity = null;

        try {
            entity = categoryMapper.selectById(id);
        } catch (Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        CategoryDO domain = getDomain(entity);

        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);

        return result;
    }


    @Override
    public ResultDO remove(String id) {


        ResultDO result = getEntity(id, new ResultDO());

        CategoryEntity entity = (CategoryEntity) result.getModel(ResultDO.SECOND_MODEL_KEY);

        //被删除的子类目都要被删除
        QueryWrapper<CategoryEntity> wrapper = new QueryWrapper<>();
        wrapper.likeRight("code", entity.getCode());

        int res = -1;
        try {
            res = categoryMapper.delete(wrapper);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if (res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.CATEGORY_DELETE_ERROR);
            logger.debug("error code：" + ErrorCode.CATEGORY_DELETE_ERROR.getCode() + " msg" + ErrorCode.CATEGORY_DELETE_ERROR.getMsg());
            return result;
        }

        return result;
    }

    @Override
    public ResultDO find(CategoryQueryDO query) {

//        CategoryEntity entity = new CategoryEntity();

        ResultDO result = new ResultDO();

//        if (!result.isSuccess()) {
//            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
//            return result;
//        }

        QueryWrapper<CategoryEntity> wrapper = new QueryWrapper<>();

        if (StringUtils.isNotEmpty(query.getCode())) {
            wrapper.likeRight("code", query.getCode());
        }

        List<CategoryEntity> list;

        try {
            list = categoryMapper.selectList(wrapper);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }
        List<CategoryDO> doList = getDomainList(list);

        //获取父节点
        String categoryId="";

        if (StringUtils.isNotEmpty(query.getCode())) {

            for (CategoryDO category:doList) {
                if(category.getCode()==query.getCode()){
                    categoryId=category.getCategoryId();
                }
            }

        }

        String finalCategoryId = categoryId;

        List<CategoryDO> treeList = doList.stream()
                .filter(e -> Objects.equals(e.getCategoryId(), finalCategoryId))
                .map(e -> {
                    e.setCategoryList(getChildList(e, doList));
                    return e;
                }).collect(Collectors.toList());


        result.setModel(ResultDO.FIRST_MODEL_KEY, treeList);

//        Page<CategoryEntity> page = new Page<>(query.getCurrentPage(), query.getPageSize());
//
//        IPage<CategoryEntity> iPage = null;
//        try {
//            iPage = categoryMapper.selectPage(page, wrapper);
//        } catch (Exception e) {
//            result.setSuccess(false);
//            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
//            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
//            return result;
//        }
//
//        List<CategoryDO> doList = getDomainList(iPage.getRecords());
//
//        PageDO<CategoryDO> pageDO = new PageDO<>();
//
//        pageDO.setCurrentPage(iPage.getCurrent());
//        pageDO.setPageCount(iPage.getPages());
//        pageDO.setPageSize(iPage.getSize());
//        pageDO.setRowCount(iPage.getTotal());
//        pageDO.setData(doList);
//        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);
        return result;
    }

    /**
     * 通过流的形式递归查询子节点
     *
     * @return
     */

    private List<CategoryDO> getChildList(CategoryDO root, List<CategoryDO> list) {

        List<CategoryDO> childList = list.stream()
                .filter(e -> Objects.equals(e.getCategoryId(), root.getId()))
                .map(e -> {
                    e.setCategoryList(getChildList(e, list));
                    return e;
                }).collect(Collectors.toList());

        return childList;
    }


    private CategoryDO getDomain(CategoryEntity entity) {
        ResultDO result = new ResultDO();
        //判断房源对象是否为空，为空就返回 空，不为空就进行下面的代码
        if (entity == null) return null;
        CategoryDO domain = new CategoryDO();
        DateUtil.dateToString(entity.getCreateDate(),DateUtil.DATE_FORMAT);
        DateUtil.dateToString(entity.getModifiDate(),DateUtil.DATE_FORMAT);
        if (!result.isSuccess()) {
            return null;
        }
        domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

        return domain;
    }


    private List<CategoryDO> getDomainList(List<CategoryEntity> list) {
        //创建一个名为dolist的房源do类型的 list集合
        List<CategoryDO> doList = new ArrayList<>();
        //判断传入的list的集合的size是否大于0
        if (list.size() > 0) {
            //大于0是，遍历list，创建do类型的对象 调用getdomain方法
            for (CategoryEntity entity : list) {

                CategoryDO domain = this.getDomain(entity);
                //判断得到的domain 是否为空 不为空 就往dolist集合里面添加domian 为空就返回空
                if (domain == null) {
                    return null;
                }
                doList.add(domain);
            }
        } else {
            return null;
        }

        return doList;

    }


    /**
     * 根据id查询出实体类
     *
     * @param id
     * @return
     */
    public ResultDO getEntity(String id, ResultDO result) {


        CategoryEntity entity = null;

        try {
            entity = categoryMapper.selectById(id);
        } catch (Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }
        result.setModel(ResultDO.SECOND_MODEL_KEY, entity);
        return result;
    }

    /**
     * 查询同级类目的code最大值
     *
     * @param categoryId
     * @return
     */

    private ResultDO getMaxCode(String categoryId, ResultDO result) {

        if (result == null) {
            return null;
        }

        List<CategoryEntity> list;

        try {
            list = categoryMapper.selectList(Wrappers.<CategoryEntity>lambdaQuery().eq(CategoryEntity::getCategoryId, categoryId).groupBy(CategoryEntity::getCode).orderByDesc(CategoryEntity::getCode));
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        result.setModel(ResultDO.FIRST_MODEL_KEY, list.size() > 0 && list != null ? Integer.parseInt(list.get(0).getCode().substring(list.get(0).getCode().length() - 2)) : -1);
        return result;
    }


}
